﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ArtificialIntelligence.MovementComponent.AStar;
using Microsoft.Xna.Framework;
using XNA_2DFramwork;

namespace ArtificialIntelligence.CombatComponent
{
    public class InferenceMachine : VisualObject
    {
        public static List<Schedule> _missions = new List<Schedule>();
        public static List<PathNode> _domain = new List<PathNode>();
        GameSensor gameSensor;

        public List<Agent> _LAgents = new List<Agent>();
        public List<Agent> _lNeedDesicionAgents = new List<Agent>();
        public List<Agent> _lIdealgents = new List<Agent>();
        
        public int MinimumHealth;

        public Schedule ScheduleAttack = new Schedule( ScheduleType.AttackEnemy);
        public Schedule ScheduleGetObject = new Schedule(ScheduleType.GetObject);
        public Schedule ScheduleFlee = new Schedule(ScheduleType.Flee);


        public void GetPathPoints()
        {
            foreach (VisualObject visualObject in _lVisualObject)
            {
                _domain.Add(new PathNode(visualObject.Position,MovementCommad.Walk));
                _domain.Add(new PathNode(new Vector2( visualObject.Position.X-10,visualObject.Position.Y-10), MovementCommad.Walk));
            }
        }

        public InferenceMachine(Game game) : base(game)
        {
            ScheduleAttack = new Schedule( ScheduleType.AttackEnemy);
            ScheduleAttack.scheduleType = ScheduleType.AttackEnemy;
            ScheduleGetObject = new Schedule(ScheduleType.GetObject);
            ScheduleGetObject.scheduleType = ScheduleType.GetObject;
            ScheduleFlee = new Schedule(ScheduleType.Flee);
            ScheduleAttack.scheduleType = ScheduleType.Flee;
            ScheduleAttack.Weigth = 3;
            ScheduleFlee.Weigth = 2;
            gameSensor = new GameSensor(game);

        }
        public void AssignSchedules(List<Schedule>LSchedules,List<Agent>LAgents)
        {

            #region 
            //foreach (Schedule schedule in LSchedules)
            //{
            //    foreach (Agent agent in LAgents)
            //    {
            //        AssignSchedule(agent, schedule);
            //        break;
            //    }
            //}
            #endregion
            //int CountSchedule = LSchedules.Count;
            //int CountAgents = LAgents.Count;
            for (int i = 0; i <= LSchedules.Count;i++ )
            {
                i = 0;
                for (int j =0; j < LAgents.Count; j++ )
                {
                    AssignSchedule(LAgents[j],LSchedules[i]);
                    //LSchedules.Remove(LSchedules[j]);
                    //LAgents.Remove(LAgents[i]);
                    //CountAgents--;
                    LAgents.Remove(LAgents[j]);
                    break;
                }
                //CountSchedule--;
                LSchedules.Remove(LSchedules[i]);
                
            }
        }

        public void AssignSchedule(Agent agent, Schedule schedule)
        {
            ScheduleType scheduleType = schedule.scheduleType;
            switch (scheduleType)
            {
                case ScheduleType.GetWeapon:
                    schedule.Priority = 2;
                    break;
                case ScheduleType.GetObject:
                    schedule.Priority = 1;
                    break;
            }    
            agent.LAgentSchedules.Add(schedule);
            //_missions.Remove(schedule);
            //_lIdealAgents.Remove(agent);
            agent.AgentState = AgentState.Working;
        }

    
        public override void Update()
        {
            gameSensor.GetState();
            GetIdealAgents();
            GetPathPoints();
            
            if ((_missions.Count !=0 && this._lIdealgents.Count !=0))
                AssignSchedules(_missions, this._lIdealgents);

            foreach (Agent agent in _LAgents)
            {
                //agent.EnemySensor.Update();
                if ((agent.EnemySensor.sensedItem.SensorState == SensorState.SeeingEnemy) || (agent.EnemySensor.sensedItem.SensorState == SensorState.SeriousDamage))
                {
                    _lNeedDesicionAgents.Add(agent);
                }
                if (agent.AgentState == AgentState.Ideal)
                {

                }
            }
            if (_lNeedDesicionAgents.Count != 0)
                TakeAction(_lNeedDesicionAgents);
            
        }

        private void TakeAction(List<Agent> lNeedDesicionAgents)
        {
           // SensorState state = new SensorState();
            foreach (Agent lNeedDesicionAgent in lNeedDesicionAgents)
            {
                // state = lNeedDesicionAgent.EnemySensor.GetState();
              //  if (IsHigherValue(lNeedDesicionAgent, lNeedDesicionAgent.EnemySensor))
               // {
                    HandleState(lNeedDesicionAgent);
                //}
            }
        }

        #region IsHigherValue
        //public bool IsHigherValue(Agent agent, EnemySensor sensor)
        //{
        //    if (agent.RunningSchedule.Priority < sensor.sensedItem._value)
        //    {
        //        return true;
        //    }
        //    else
        //    {
        //        return false;
        //    }
        //}
        #endregion

        public void HandleState(Agent agent)
        {
            if (agent.EnemySensor.sensedItem.SensorState == SensorState.SeeingEnemy)
            {
                if ( ScheduleAttack.Weigth > ScheduleFlee.Weigth)
                {
                    agent.LAgentSchedules.Add(ScheduleAttack);
                    //agent.SetRunningSchedule(ScheduleAttack);
                    agent.RunSchedules();
                }
                else
                {
                    if (ScheduleAttack.Weigth < ScheduleFlee.Weigth)
                    {
                        agent.LAgentSchedules.Add(ScheduleFlee);
                        //agent.SetRunningSchedule(ScheduleFlee);
                        agent.RunSchedules();
                    }
                    else
                    {
                        if (agent.Life < MinimumHealth)
                        {
                            
                            agent.LAgentSchedules.Add(ScheduleFlee);
                            //agent.SetRunningSchedule(ScheduleFlee);
                            agent.RunSchedules();
                        }
                        else
                        {
                            agent.LAgentSchedules.Add(ScheduleAttack);
                            //agent.SetRunningSchedule(ScheduleAttack);
                            agent.RunSchedules();
                        }
                    }
                }
                
            }
        }

        public override void Draw()
        {
            
        }

        public void GetIdealAgents()
        {
            foreach (Agent lAgent in _LAgents)
            {
                if (lAgent.AgentState == AgentState.Ideal)
                    _lIdealgents.Add(lAgent);
            }
        }


        public void CreateSchedule(ScheduleType scheduleType)
        {
            Schedule schedule = new Schedule(scheduleType);
            _missions.Add(schedule);
        }
    }
}
